/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007-2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.security.ws.client;

import java.util.HashMap;
import java.util.Map;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;

/**
 * WSS4J handler that use the current authenticated user credentials for the
 * called web service.
 */
public class SpringSecurityWSS4JOutInterceptor
    extends AbstractWSS4JInterceptor
{

  /**
   * the password callback to use with spring security.
   */
  private static final SpringSecurityPasswordCallback SPRING_SECURITY_PASSWORD_CALLBACK = new SpringSecurityPasswordCallback();



  /**
   * Intercepts a message. Interceptors should NOT invoke handleMessage or
   * handleFault on the next interceptor - the interceptor chain will take care
   * of this.
   * 
   * @param message
   *          the message to work on
   * @throws Fault
   *           if an error occured
   */
  public void handleMessage(SoapMessage message)
      throws Fault
  {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null) {
      return;
    }
    Map<String, Object> outProperties = new HashMap<String, Object>();
    // Action to perform : user token
    outProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    // Password type : plain text
    outProperties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
    // User name to send
    outProperties.put(WSHandlerConstants.USER, authentication.getName());
    // Callback used to retrieve password for given user.
    outProperties.put(WSHandlerConstants.PW_CALLBACK_REF, SPRING_SECURITY_PASSWORD_CALLBACK);

    new WSS4JOutInterceptor(outProperties).handleMessage(message);
  }

}
